package com.dmc.service.impl;

import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotations.TableField;
import com.dmc.dict.*;
import com.dmc.entity.OrderDetail;
import com.dmc.mapper.*;
import com.dmc.model.*;
import com.dmc.service.DistributionService;
import com.dmc.service.OrdersService;
import com.dmc.service.PayService;
import com.dmc.util.DecimalUtil;
import com.dmc.util.id.IdUtil;
import com.dmc.util.util.OrderCodeUtil;
import com.dmc.util.util.SpringApplicationContextUtil;
import com.dmc.vo.PaymentVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 第三方支付接口
 */
@Service
@Slf4j
public abstract class AbstractPayServiceImpl implements PayService {

    public static  Map<String, Map<String,String>> payMap = new ConcurrentHashMap<>();

    @Autowired
    private PaymentMapper paymentMapper;

    @Autowired
    private DistributionService distributionService;
    
    @Autowired
    private OrdersService ordersService;

    @Autowired
    private CashOutOrdersMapper cashOutOrdersMapper;

    @Autowired
    private DistributionOrderMapper distributionOrderMapper;

    @Autowired
    private DistributionGoodsMapper distributionGoodsMapper;

    @Autowired
    private DistributionGoodsPackageMapper distributionGoodsPackageMapper;

    static{
        payMap = new ConcurrentHashMap<>();
        //微信 暂时只支持小程序支付
        Map<String,String> wxMap = new HashMap<>();
        wxMap.put("appId", "wx8bb75d0aec3c7393");
        wxMap.put("mchId", "1601232483");
        wxMap.put("apiKey", "48b8b19309a23e52d72d0171a4d0f461");//48b8b19309a23e5=2d72d0171a4d0f463
        wxMap.put("certPath", File.separator+"src"+File.separator+"main"+File.separator+"resources"+File.separator+"cert"+File.separator+"apiclient_cert.p12");
        String wxKey = PayTypeDict.PAY_TYPE_WECHAT.getCn()+ PayModeDict.PAY_MODE_MINI_APP.getCn();
        payMap.put(wxKey, wxMap);
        //支付宝 暂时只支持native支付
        Map<String,String> aliMap = new HashMap<>();
        aliMap.put("pId", "2088831994527453");
        aliMap.put("appId", "2021001182606508");
        aliMap.put("account", "825780219@qq.com");
        aliMap.put("publicKey", "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArpvlKcwWp39+RghlkkWngyTBoxJBh6N91WJ6mqL57AjUyaTAdvAc7YmqPwvvLup18TK+44moO2PcZBZUY9SZY65BRL3nxzdzL0ymy4ZsnbearxiTpHZ+GX4vRQeNu9wsm9oyIefWOZg4ApMUeXjVdiHAtFAMFYWZtUbL4t9bRM1+qXE+fx2u+5Dtik/B0U3DM0uKjuQRsVjhW1KzJg6Jveug9w3PZoeSp8lm0c4e98gFRAz4a9AFeg2FzyzZ6hs6b2aQryVQbt+wZJgW7q3+DVk+FLxNBH4b3/bc6tLJJW288Jc76enDbJcZET8NBXiJE3or5oauCiAfUKpbNIejtwIDAQAB");
        aliMap.put("privateKey", "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC5g8Q0SBBxWApFR+Y1825ok3+WQGzIDKIxE3MenyS9Zjc8r8Snggd7RhcSIyvAiq+gkPs9tJHxsmOqyqG+7YNDPscUq5E8g2swZA8xE1ZhB7DOd2YRU+a/LIlmi0WA4ffrbMgd/E5Ku108g2C/h8F7d11z9pbUY1oG7v7eiUIe0A4hhC82uGmTtw5IpLGwQQ6nDF5U+IEG6wbDbelYfgokg6yyu2+OgT2Vh2256d+mMJbVtDdtLxnArniHMTnBUWTd/f/SgRZ6Gisqyxq2tKe1BW6dg93hmxaZUMyS8gOOKMcdRXq4iBRlxa99KqrLoq01pBdXWXWBO2PgFn9qIAjbAgMBAAECggEAcoM5q6QIMk7MGDPnkMnxDzBtA0xFWb8ipvSAjRhjT143HojI9TU4dQmw2AtJyJJTEuQrkc1SgUVCbHykFvz5l5q6vLGi9x2QHtDE5+At47shknD1WiDWQI+3SMsTXhkeNf5yEMBbe5noVaArKk8cSaBG2XwPYo7pVXpVbPyBCg8I5z0/qo5TNvWBAIwGcr2c6TEOeh69fuRmwvj3hA9gBXzvNALzzxqJzIDZuzkyJC303MIhuxwBp3Ezqx+Ez8naXNugXT39z4weBlSkVyy3fiq9Fd49HcIjCByao/PhjMYmaOWoSfO1nV5xJqvs13/RZKxLrYCwXGdrP+lWziMOwQKBgQDy+BuIJLBHvZxNkvMW62XCfSO4bi2meG3epq5pwHrT67JglCGTcpUEeTM91MFAox6I69arF/kpg33fve5k85LrNHP3duVL9ApzHGEFdbJHkIiLmnhvL6STeOewAmY3w79XR37vHyXCUkB46oVV/k6y45OZRHRifoPTZknO8lRFawKBgQDDdtOkx+dQ0j1he6hsI1x4bjcemQLsfjNpCxgaOPuny2j3d8bUNg5QRyDm7kpq6OWF0LYBszLLec7u8tRkcesDEVi9t8UVBZmTHA3ALdqA+uxEcwUI4zNsFyk+LScHgwgtj035MWZFqoxZGt85d84OKaEdR4FEY4bgqHJ4Z1S2UQKBgBkjvM2IZkj2AH8yTj632o6WHiUOGWEZIt0fx/ofNVZKE+nUSekUuQB+fePO6LQEbLtkE5EeaOR3u4V0BH+jiDcX9UvMnIsQVCh27j7/X5PyC37OW9m9Rz0PDIH0rZjlgx3HwwWA5opFsnAQa/1q07/EtlfsclJinsc31Tk5b6jDAoGAH194Mu+fEhrcnUPy0YCPfAj8sd2PWZQb/lU4hiT1R4Zfj7Da6f7PJ1VzU32V1jkRdfv86qLvmTcw3qt9Ka4bMX/cRX80k941OyZ6kokJlEAyIf5wJXAKNeQ1y3QF2q/OZTmmI0QpjS8FnduxTpELMry9zmxGtEphQLfov6ieMTECgYEAguD0P1sWjc5MGTnszdNhNBrCG7OlnYVRBRf8N0u/RJPFdQeZQhBQdwcd2v1JbXGcURccuC/xFXhZ/IgJwE034ZmoMWl+YR2UPo42Rioj/hTwq0dodd2lpb+bnIxDqd38nQXVNL2l9bqiWOalkyxbInHRUdh4vQ02PH6U4Cm9yFk=");
        String aliKey = PayTypeDict.PAY_TYPE_ALIPAY.getCn()+ PayModeDict.PAY_MODE_MINI_NATIVE.getCn();
        payMap.put(aliKey, aliMap);
        //银联待定
    }

    public static PayService getPayService(String payType, String payModel){
        if (StringUtils.isBlank(payType)){
            return SpringApplicationContextUtil.getBean(WeChatPayServiceImpl.class);
        }
        PayService payService = null;
        if(PayTypeDict.PAY_TYPE_WECHAT.getCn().equalsIgnoreCase(payType)){
            payService = SpringApplicationContextUtil.getBean(WeChatPayServiceImpl.class);
        }else if(PayTypeDict.PAY_TYPE_ALIPAY.getCn().equalsIgnoreCase(payType)){
            payService = SpringApplicationContextUtil.getBean(AliPayPayServiceImpl.class);
        }
        return payService;
    }

    public static PayService getOrder(String payType, String payModel){
        if (StringUtils.isBlank(payType)){
            return SpringApplicationContextUtil.getBean(WeChatPayServiceImpl.class);
        }
        PayService payService = null;
        if(PayTypeDict.PAY_TYPE_WECHAT.getCn().equalsIgnoreCase(payType)){
            payService = SpringApplicationContextUtil.getBean(WeChatPayServiceImpl.class);
        }else if(PayTypeDict.PAY_TYPE_ALIPAY.getCn().equalsIgnoreCase(payType)){
            payService = SpringApplicationContextUtil.getBean(AliPayPayServiceImpl.class);
        }
        return payService;
    }
    /**
     * 获取支付相关记录实例
     */
    Payment getPayment(Long userId, Integer payType,Integer orderType, String orderId, Long checkoutId, boolean isNeedExist,BigDecimal amount){
        //根据订单号查询对应类型的线上支付单据
        Payment payment = null;
        if(checkoutId != null){
            Payment query = new Payment();
            query.setCheckoutId(checkoutId);
            payment = paymentMapper.selectOne(query);
        }
        if(payment ==null){
            Assert.isTrue(!isNeedExist,"参数错误,无对应支付单据");
            payment = new Payment();
            payment.setPayNo(OrderCodeUtil.getPayCode(userId));
            payment.setUserId(userId);
            payment.setPayType(payType);
            payment.setOrderId(orderId);
            payment.setCheckoutId(IdUtil.generateId());
            payment.setAmount(amount);
            payment.setOrderType(orderType);
        }
        return payment;
    }

    /**
     * 校验支付金额和订单金额 必须小于等于订单金额
     * @param amount
     * @param orderAmount
     * @return
     */
    boolean checkAmount(BigDecimal amount, BigDecimal orderAmount){
        boolean result = amount.divide(new BigDecimal("100"),1,BigDecimal.ROUND_HALF_UP).compareTo(orderAmount)<=0;
        return result;
    }
    /**
     * 针对分销和提现订单将订单ID转换为订单编码
     */
    void replaceOrderIdToNo(PaymentVo payment){
        if(payment == null){
            return;
        }
        Integer orderType = payment.getOrderType();
        String orderId = payment.getOrderId();
        if(orderType!=null && StringUtils.isNotBlank(orderId)){
            if(OrderTypeDict.ORDER_TYPE_DISTRBUTION.getCn() == orderType){
                long orderIdLong = Long.valueOf(orderId);
                DistributionOrder distributionOrder = distributionOrderMapper.selectById(orderIdLong);
                payment.setOrderId(distributionOrder.getOrderNo());
            }else if(OrderTypeDict.ORDER_TYPE_TRANSFER.getCn() == orderType){
                long orderIdLong = Long.valueOf(orderId);
                CashOutOrders cashOutOrders = cashOutOrdersMapper.selectById(orderIdLong);
                payment.setOrderId(cashOutOrders.getOrderCode());
            }
        }
    }

    /**
     * 支付时订单相关前置处理
     * @param payType
     * @param orderNo
     * @return
     */
    JSONObject payOrderExePre(Long checkoutId,Integer payType, String orderNo, Integer orderType,String amount){
        JSONObject result = new JSONObject();
        StringBuffer goods = new StringBuffer();
        if(OrderTypeDict.ORDER_TYPE_GOODS.getCn() == orderType){
            String checkResult=ordersService.payCheckSkuNum(orderNo);
            Assert.isTrue(checkResult=="",checkResult);
            BigDecimal orderFinalAmount=ordersService.getFinalAmountByOrderNo(orderNo);
            if(orderFinalAmount!=null) {
                BigDecimal finalAmount=DecimalUtil.mul(orderFinalAmount.toString(),"100");
                log.debug(orderNo+"支付"+amount + "支付金额必须等于订单应付金额:" + orderFinalAmount+",应付金额(分):"+finalAmount);
                result.put("amount", amount);
            }
            //更新支付单据
            ordersService.payOrderProcess(orderNo,checkoutId);
        }else if(OrderTypeDict.ORDER_TYPE_DISTRBUTION.getCn() == orderType){
            //分销商支付处理
            DistributionOrder distributionOrder = distributionOrderMapper.getOrderByOrderNo(orderNo);
            //校验金额
            Integer distributionOrderType = distributionOrder.getOrderType();
            if(DistriButionOrderTypeDict.DISTRIBUTION_PAY_TYPE_1.getCn() == distributionOrderType){
                Long distributionGoodsId = distributionOrder.getDistributionGoodsId();
                DistributionGoodsPackage distributionGoodsPackage = distributionGoodsPackageMapper.selectById(distributionGoodsId);
                //获取商品详情
                goods.append(distributionGoodsPackage.getPackageName());
            }else{
                Long distributionGoodsId = distributionOrder.getDistributionGoodsId();
                DistributionGoods distributionGoods = distributionGoodsMapper.selectById(distributionGoodsId);
                //获取商品详情
                goods.append(distributionGoods.getDistributionName());
            }
            Long distributionGoodsId = distributionOrder.getDistributionGoodsId();
            DistributionGoods distributionGoods = distributionGoodsMapper.selectById(distributionGoodsId);
            BigDecimal price = distributionOrder.getPrice();
            BigDecimal amountDec = new BigDecimal(amount).divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
            Assert.isTrue(price.compareTo(amountDec) == 0,"金额有误");
            //保存支付单据ID
            distributionOrder.setCheckoutId(checkoutId);
            distributionOrderMapper.updateById(distributionOrder);
            result.put("orders", distributionOrder);

        }else if(OrderTypeDict.ORDER_TYPE_TRANSFER.getCn() == orderType){

        }
        result.put("orderDetail", goods.toString());
        return result;
    }

    /**
     * 支付回调时对订单相关处理
     * @param orderNo 
     * @param orderType
     * @return
     */
    void payCallBackOrderExePre(String orderNo,Integer orderType,Integer payType,Integer distriButionPayType){
        log.debug("支付回调时对订单相关处理payCallBackOrderExePre");
        if(OrderTypeDict.ORDER_TYPE_GOODS.getCn() == orderType){
            log.debug("支付回调时对订单相关处理{商品订单}:"+orderType);
            if(payType!=null) {
                log.debug("支付回调时对订单相关处理{商品订单}:"+orderType);
                //商品支付成功回调
                ordersService.payOrderProcess(payType, orderNo, orderType);
            }
        }else if(OrderTypeDict.ORDER_TYPE_DISTRBUTION.getCn() == orderType){
            //分销商订单支付回调处理
            DistributionOrder orderByOrderNo = distributionOrderMapper.getOrderByOrderNo(orderNo);
            Assert.notNull(orderByOrderNo,"参数错误,没有相关订单");
            Integer distributionOrderType = orderByOrderNo.getOrderType();
            if(DistriButionOrderTypeDict.DISTRIBUTION_PAY_TYPE_1.getCn() == distributionOrderType){
                distributionService.packAgePostProcess(orderByOrderNo.getId(),distriButionPayType,false,false);
            }else{
                distributionService.postProcess(orderByOrderNo.getId(),distriButionPayType,false,false);
            }

        }else if(OrderTypeDict.ORDER_TYPE_TRANSFER.getCn() == orderType){

        }
    }



    /**
     * 退款时订单相关前置处理
     * @param payType
     * @param orderId
     * @return
     */
    JSONObject refundOrderExePre(Integer payType, String orderId, Integer orderType){
        JSONObject result = new JSONObject();
        if(OrderTypeDict.ORDER_TYPE_GOODS.getCn() == orderType){
            //校验退款金额
            BigDecimal refundAmount=ordersService.getRefundAmountByOrderNo(orderId);
//            BigDecimal payAmount=new BigDecimal(refundAmount);
//            Assert.isTrue(payAmount.compareTo(orderAmount)==0,"支付金额必须等于订单应付金额");
        }else if(OrderTypeDict.ORDER_TYPE_DISTRBUTION.getCn() == orderType){
            // 分销商订单退款处理 TODO
        }else if(OrderTypeDict.ORDER_TYPE_TRANSFER.getCn() == orderType){

        }
        return result;
    }


    /**
     * 退款时对订单相关处理
     * @param orderId
     * @param orderType
     * @return
     */
    void refundBackOrderExePre(String orderId,Integer orderType,Object order){
        if(OrderTypeDict.ORDER_TYPE_GOODS.getCn() == orderType){
            // 商品订单退款处理,更新订单状态
            ordersService.refundBackOrderExePre(orderId);
        }else if(OrderTypeDict.ORDER_TYPE_DISTRBUTION.getCn() == orderType){
            // 分销商订单退款处理 TODO
        }else if(OrderTypeDict.ORDER_TYPE_TRANSFER.getCn() == orderType){

        }
    }

}
